package ar.edu.utn.frba.dds.aterrizar;

import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

import ar.edu.utn.frba.dds.aterrizar.aerolineas.AerolineaOceanicAdapter;
import ar.edu.utn.frba.dds.aterrizar.aerolineas.OperadorDeAerolineas;
import ar.edu.utn.frba.dds.aterrizar.busquedas.Busqueda;
import ar.edu.utn.frba.dds.aterrizar.busquedas.CondicionesExtra;
import ar.edu.utn.frba.dds.aterrizar.busquedas.CondicionesExtraBuilder;
import ar.edu.utn.frba.dds.aterrizar.busquedas.RangoFechas;
import ar.edu.utn.frba.dds.aterrizar.busquedas.Vuelo;
import ar.edu.utn.frba.dds.aterrizar.usuarios.Estandar;
import ar.edu.utn.frba.dds.aterrizar.usuarios.NoPaga;
import ar.edu.utn.frba.dds.aterrizar.usuarios.Usuario;
import ar.edu.utn.frba.dds.aterrizar.usuarios.VIP;

import com.oceanic.AerolineaOceanic;
import com.oceanic.AsientoDTO;

public class AerolineaOceanicTest {

    AerolineaOceanicAdapter MockDeAerolineaOceanicAdapter;
    AerolineaOceanic MockDeAerolineaOceanic;
    OperadorDeAerolineas operador;
    
    Usuario usuarioEstandarsinRestriccion;
    Usuario usuarioVIPSinRestricciones;
    Usuario usuarioNoPagaSinRestriccion;
    Usuario usuarioVIPConRestriccionesDeClaseYUbicacion;
    
    Busqueda busquedaSinRestriccion1;
    Busqueda busquedaSinRestriccion2;
    Busqueda busquedaConRestriccionDeClaseYUbicacion;
    Busqueda busquedaConRestriccionDeClaseYUbicacion2;
    
    CondicionesExtraBuilder condicionesExtraBuilderEmptyBuilder;
    CondicionesExtraBuilder condicionesExtraBuilderUbicacionYClaseBuilder;
    CondicionesExtra condicionesExtraEmpty;
    CondicionesExtra condicionesExtraEjecutivaYPasillo;
    
    List<AsientoDTO> asientosOceanicOrigen;
    List<AsientoDTO> asientosOceanicOrigenYDestino;
    List<AsientoDTO> asientosOceanicConClaseTurista;
    List<AsientoDTO> asientoOceanic3;
    
    
    @Before
    public void setUp() {
    	
    	MockDeAerolineaOceanic = mock(AerolineaOceanic.class);
    	OperadorDeAerolineas.createInstance();
    	operador = OperadorDeAerolineas.getInstance();
    	MockDeAerolineaOceanicAdapter = AerolineaOceanicAdapter.getInstance();
        usuarioEstandarsinRestriccion = new Usuario("Nombre1", new Estandar(),"Ape1","28.111.222");
        usuarioVIPSinRestricciones = new Usuario("Nombre2", new VIP(),"Ape2","28.111.223");
        usuarioNoPagaSinRestriccion = new Usuario("Nombre3", new NoPaga(), "Ape3", "28.111.224");
        usuarioVIPConRestriccionesDeClaseYUbicacion = new Usuario("Nombre4", new VIP(), "Ape4", "28.111.225");
        
        condicionesExtraBuilderEmptyBuilder = new CondicionesExtraBuilder();
        condicionesExtraEmpty = condicionesExtraBuilderEmptyBuilder.build();
        condicionesExtraBuilderUbicacionYClaseBuilder = new CondicionesExtraBuilder();
        condicionesExtraEjecutivaYPasillo = condicionesExtraBuilderUbicacionYClaseBuilder.addClase("E").addUbicacion("P").addRangoPrecio(3000,7000).build();
        
        busquedaSinRestriccion1 = new Busqueda("_BS", "SLA", new RangoFechas("15/08/2012", null, null, null), condicionesExtraEmpty);
        busquedaSinRestriccion2 = new Busqueda("SLA", "_NY", new RangoFechas("23/12/2012", null, null, null), condicionesExtraEmpty);
        busquedaConRestriccionDeClaseYUbicacion = new Busqueda("SLA", "_NY", new RangoFechas("23/12/2012", null, null, null), condicionesExtraEjecutivaYPasillo);
        busquedaConRestriccionDeClaseYUbicacion2 = new Busqueda("SLA", "_BS", new RangoFechas("13/09/2012", null, null, null), condicionesExtraEjecutivaYPasillo);
        
    	/**
		* Asientos para Origen
    	*/  
        asientosOceanicOrigen = new ArrayList<AsientoDTO>();
               
        asientosOceanicOrigen.add(new AsientoDTO("OC100",10,"15/08/2012","17/08/2012","10:35","05:35",new BigDecimal("3150.98"),"Ejecutiva","Pasillo",false,"_BS","SLA"));
        asientosOceanicOrigen.add(new AsientoDTO("OC100",11,"15/08/2012","17/08/2012","10:35","05:35",new BigDecimal("3150.98"),"Ejecutiva","Centro",false,"_BS","SLA"));              
        asientosOceanicOrigen.add(new AsientoDTO("OC100",12,"15/08/2012","17/08/2012","10:35","05:35",new BigDecimal("3150.98"),"Ejecutiva","Ventana",false,"_BS","SLA"));             
        asientosOceanicOrigen.add(new AsientoDTO("OC100",30,"15/08/2012","17/08/2012","10:35","05:35",new BigDecimal("6150.98"),"Primera","Pasillo",true,"_BS","SLA"));                
        
        when(MockDeAerolineaOceanic.asientosDisponiblesParaOrigen("_BS", "15/08/2012")).thenReturn(asientosOceanicOrigen);
        
        /**
		* Asientos para Origen y Destino
    	*/
        asientosOceanicOrigenYDestino = new ArrayList<AsientoDTO>();
        
        asientosOceanicOrigenYDestino.add(new AsientoDTO("OC202",20,"13/09/2012","13/09/2012","06:40","16:18",new BigDecimal("6150.98"),"Primera","Centro",false,"SLA","_BS"));		
		asientosOceanicOrigenYDestino.add(new AsientoDTO("OC202",21,"13/09/2012","13/09/2012","06:40","16:18",new BigDecimal("4550.98"),"Ejecutiva","Pasillo",false,"SLA","_BS"));		
		asientosOceanicOrigenYDestino.add(new AsientoDTO("OC202",26,"13/09/2012","13/09/2012","06:40","16:18",new BigDecimal("4450.98"),"Ejecutiva","Ventana",true,"SLA","_BS"));		
		asientosOceanicOrigenYDestino.add(new AsientoDTO("OC202",27,"13/09/2012","13/09/2012","06:40","16:18",new BigDecimal("4450.98"),"Ejecutiva","Pasillo",false,"SLA","_BS"));   
        
        when(MockDeAerolineaOceanic.asientosDisponiblesParaOrigenYDestino("SLA", "_BS", "13/09/2012")).thenReturn(asientosOceanicOrigenYDestino);
        
        asientosOceanicConClaseTurista = new ArrayList<AsientoDTO>();
        
        asientosOceanicConClaseTurista.add(new AsientoDTO("OC042",19,"23/12/2012","24/12/2012","23:50","05:30",new BigDecimal("4100.98"),"Turista","Ventana",true, "SLA","_NY"));		
        asientosOceanicConClaseTurista.add(new AsientoDTO("OC042",20,"23/12/2012","24/12/2012","23:50","05:30",new BigDecimal("4100.98"),"Turista","Pasillo",false, "SLA","_NY"));		
        asientosOceanicConClaseTurista.add(new AsientoDTO("OC042",11,"23/12/2012","24/12/2012","23:50","05:30",new BigDecimal("4500.98"),"Ejecutiva","Ventana",false, "SLA","_NY"));		
        asientosOceanicConClaseTurista.add(new AsientoDTO("OC042",12,"23/12/2012","24/12/2012","23:50","05:30",new BigDecimal("4500.98"),"Ejecutiva","Centro",true,"SLA","_NY"));		
        asientosOceanicConClaseTurista.add(new AsientoDTO("OC042",13,"23/12/2012","24/12/2012","23:50","05:30",new BigDecimal("4500.98"),"Ejecutiva","Pasillo",false,"SLA","_NY"));
        
        when(MockDeAerolineaOceanic.asientosDisponiblesParaOrigenYDestino("SLA", "_NY", "23/12/2012")).thenReturn(asientosOceanicConClaseTurista);
    }
    
    @Test
	public void calculoDePrecioDeUnVueloParaUsuarioEstandar()  {
		Vuelo vuelo = operador.encontrarVueloPorCodigo("OC100","10"); 
		assertEquals(3623.627, vuelo.getPrecioPara(usuarioEstandarsinRestriccion), 0.001);
	}
    
	@Test
	public void calculoDePrecioDeUnVueloParaUsuarioVIP() {
		Vuelo vuelo = operador.encontrarVueloPorCodigo("OC100","10"); 
		assertEquals(3623.627, vuelo.getPrecioPara(usuarioVIPSinRestricciones), 0.001);
	}
	
	@Test
	public void calculoDePrecioDeUnVueloParaUsuarioNoPaga() {
		Vuelo vuelo = operador.encontrarVueloPorCodigo("OC100","10"); 
		assertEquals(3643.627, vuelo.getPrecioPara(usuarioNoPagaSinRestriccion), 0.001);
	}
	
	@Test
	public void duracionDeVueloEnMinutos() {
		Vuelo vuelo = operador.encontrarVueloPorCodigo("OC100","10");
		int duracion = vuelo.getDuracionEnMinutos();
		assertEquals(43*60, duracion);
	}

	@Test
	public void duracionDeVueloEnString() {
		Vuelo vuelo = operador.encontrarVueloPorCodigo("OC100","10");
		String duracion = vuelo.getDuracionEnStringHora();
		assertEquals("43:00", duracion);
	}
	
	@Test
	public void cantidadVuelosParaUnUsuarioVIPsinRestriccionesExtra() {
		ArrayList<Vuelo> vuelos = usuarioVIPSinRestricciones.buscarVuelos(busquedaSinRestriccion1);
		assertEquals(4, vuelos.size());
	}
	
	@Test
	public void cantidadVuelosParaUnUsuarioEstandarsinRestriccionesExtra() {
		ArrayList<Vuelo> vuelos = usuarioEstandarsinRestriccion.buscarVuelos(busquedaSinRestriccion2);		
		assertEquals(5, vuelos.size());
	}
	
	@Test
	public void cantidadVuelosParaUnUsuarioNoPagasinRestriccionesExtra() {
		ArrayList<Vuelo> vuelos = usuarioNoPagaSinRestriccion.buscarVuelos(busquedaSinRestriccion2);
		assertEquals(5, vuelos.size());
	}
	
	@Test
	public void cantidadVuelosParaVIPConRestriccionesDePrimeraClaseYUbicacionCentro() {
		ArrayList<Vuelo> vuelos = usuarioVIPConRestriccionesDeClaseYUbicacion.buscarVuelos(busquedaConRestriccionDeClaseYUbicacion);
		assertEquals(1, vuelos.size());
	}
	
	@Test
	public void cantidadDeVuelosSinIncluirReservados() {
		ArrayList<Vuelo> vuelos = usuarioVIPConRestriccionesDeClaseYUbicacion.buscarVuelos(busquedaConRestriccionDeClaseYUbicacion2);
		assertEquals(2, vuelos.size());
	}
    
}